package ee.ut.re;
import static ee.ut.re.MathUtil.*;

import java.util.Date;
import java.util.Map;

import weka.core.Attribute;

import ch.hsr.geohash.GeoHash;

public class Flat {

	private final long yldpind;
	private final boolean saun;
	private final boolean rodu;
	private final Double price;
	private final String linnaOsa;
	private final Date salesDate;
	private final Double pricePerM2;
	private final long latlon;
	private final boolean keskkyte,  gaaskyte,  elkkyte,  ahjukyte, garazh, kamin;
	
	public Flat(Double price, long yldpind, boolean saun, boolean rodu, String linnaOsa, Date salesDate, 
			Double pricePerM2, String latLon, boolean keskkyte, boolean gaaskyte, boolean elkkyte, boolean ahjukyte, boolean garazh, boolean kamin) {
		this.yldpind = yldpind;
		this.saun = saun;
		this.rodu = rodu;
		this.price = price;
		this.linnaOsa = linnaOsa;
		this.salesDate = salesDate;
		this.pricePerM2 = pricePerM2;
		String[] parts = latLon.split(",");
		this.latlon = GeoHash.withBitPrecision(Double.valueOf(parts[0]),Double.valueOf(parts[1]), 60 /* MAX Precission*/).longValue();
		
		this.keskkyte = keskkyte;
		this.gaaskyte = gaaskyte;
		this.elkkyte = elkkyte;
		this.ahjukyte = ahjukyte;
		this.garazh = garazh;
		this.kamin = kamin;
		
	}
	
	
	
	public double distance(Flat that, Map<Attribute, Double> weightMap) {
		return Math.sqrt(sum(weightMap.get(NonWekaDistanceTest.LINNAOSA_ATTR) * square(osaDistance(this.linnaOsa, that.linnaOsa)),
				weightMap.get(NonWekaDistanceTest.SAUN_ATTR) *  booleanDistance(this.saun, that.saun),
				weightMap.get(NonWekaDistanceTest.KESKKYTE_ATTR) * booleanDistance(this.keskkyte, that.keskkyte),
				weightMap.get(NonWekaDistanceTest.GAASKYTE_ATTR) * booleanDistance(this.gaaskyte, that.gaaskyte),
				weightMap.get(NonWekaDistanceTest.ELKKYTE_ATTR)*  booleanDistance(this.elkkyte, that.elkkyte),
				weightMap.get(NonWekaDistanceTest.RODU_ATTR)*  booleanDistance(this.rodu, that.rodu),
				weightMap.get(NonWekaDistanceTest.GARAZH_ATTR)*  booleanDistance(this.garazh, that.garazh),
				weightMap.get(NonWekaDistanceTest.KAMIN_ATTR)*  booleanDistance(this.kamin, that.kamin)));
	}
	
	private double square(double x) {
		return Math.pow(x, 2);
	}



	private double osaDistance(String linnaOsa2, String linnaOsa3) {
		return linnaOsa2.equals(linnaOsa2) ? 0.0 : 1.0;
	}

	public Double getPrice() {
		return this.price;
	}

	public long getYldpind() {
		return yldpind;
	}

	public boolean isSaun() {
		return saun;
	}

	public boolean isRodu() {
		return rodu;
	}

	public boolean isKamin() {
		return kamin;
	}
	
	public String getLinnaOsa() {
		return linnaOsa;
	}

	public Date getSalesDate() {
		return salesDate;
	}

	public Double getPricePerM2() {
		return pricePerM2;
	}

	public long getLatlon() {
		return latlon;
	}

	public boolean isKeskkyte() {
		return keskkyte;
	}

	public boolean isGaaskyte() {
		return gaaskyte;
	}

	public boolean isElkkyte() {
		return elkkyte;
	}

	public boolean isAhjukyte() {
		return ahjukyte;
	}

	public boolean isGaraazh() {
		return this.garazh;
	}



	@Override
	public String toString() {
		return "Flat [yldpind=" + yldpind + ", saun=" + saun + ", rodu=" + rodu
				+ ", price=" + price + ", linnaOsa=" + linnaOsa
				+ ", salesDate=" + salesDate + ", pricePerM2=" + pricePerM2
				+ ", latlon=" + latlon + ", keskkyte=" + keskkyte
				+ ", gaaskyte=" + gaaskyte + ", elkkyte=" + elkkyte
				+ ", ahjukyte=" + ahjukyte + ", garazh=" + garazh + ", kamin="
				+ kamin + "]";
	}
	
	
	
}
